package com.hb.concert;

import org.aspectj.lang.annotation.*;

// @Aspect 注解表明 Audience 不仅仅是一个 POJO，还是一个切面
// Audience 类中的方法都使用注解来定义切面的具体行为（确切来说应该是定义在何时进行怎样的行为）
@Aspect
public class Audience {
    // 1、通知注解是用来创建切点的
    // 2、通知注解之一，表明通知方法会在目标方法调用之前执行
    // 3、execution 切点指示器中的 “* com.hb.concert.Performance.perform(..)” 是切点表达式。其中 * 表示我们不关心目标方法的返回值，目标方法可以返回任意类型。
    // 后面的 com.hb.concert.Performance.perform 是方法的全限定名。对于方法参数列表，我们使用两个点号(..)表明切点要选择任意的 perform() 方法，无论该方法的入参是什么。
    @Before("execution(* com.hb.concert.Performance.perform(..))")
    public void silenceCellPhones() {
        System.out.println("Silencing cell phones");
    }

    @Before("execution(* com.hb.concert.Performance.perform(..))")
    public void takeSeats() {
        System.out.println("Taking seats");
    }

    // 通知注解之一，表明通知方法会在目标方法返回后调用
    @AfterReturning("execution(* com.hb.concert.Performance.perform(..))")
    public void applause() {
        System.out.println("CLAP CLAP CLAP!!!");
    }

    // 通知注解之一，表明通知方法会在目标方法抛出异常后调用
    @AfterThrowing("execution(* com.hb.concert.Performance.perform(..))")
    public void demandRefund() {
        System.out.println("Demanding a refund");
    }

    // 通知注解之一，表明通知方法会在目标方法返回或抛出异常后调用
    @After("execution(* com.hb.concert.Performance.perform(..))")
    public void Departure() {
        System.out.println("Audience leave here");
    }
}
